package com.dykj.fireFighting.server.socialUnit.devicemanger.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dykj.fireFighting.api.base.dev.entity.DeviceType;
import com.dykj.fireFighting.api.base.system.entity.SysDirectory;
import com.dykj.fireFighting.api.base.system.service.ISysDirectoryService;
import com.dykj.fireFighting.api.base.video.entity.Video;
import com.dykj.fireFighting.api.base.video.vo.VideoPlayVo;
import com.dykj.fireFighting.api.socialUnit.devHis.entity.CrtPointVo;
import com.dykj.fireFighting.api.socialUnit.devHis.entity.CrtVo;
import com.dykj.fireFighting.api.socialUnit.devicemanger.entity.*;
import com.dykj.fireFighting.api.socialUnit.devicemanger.service.IDeviceService;
import com.dykj.fireFighting.common.core.constant.CommonConstant;
import com.dykj.fireFighting.common.core.dto.CommonDto;
import com.dykj.fireFighting.common.core.service.impl.BaseServiceImpl;
import com.dykj.fireFighting.common.core.utils.*;
import com.dykj.fireFighting.common.core.vo.LoginUserVo;
import com.dykj.fireFighting.common.core.vo.PageVo;
import com.dykj.fireFighting.common.starter.redis.service.RedisService;
import com.dykj.fireFighting.server.socialUnit.devicemanger.mapper.DeviceMapper;
import com.dykj.fireFighting.server.socialUnit.devicemanger.mapper.ManufactorMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 设备管理-智能设备
 *
 * @Author fgc
 * @Date  2021-06-22 15:55:39
 */
@Slf4j
@DubboService
@Transactional(rollbackFor = Exception.class)
public class DeviceServiceImpl extends BaseServiceImpl<DeviceMapper, Device> implements IDeviceService {
    @Autowired
    private DeviceMapper deviceMapper;
    @Autowired
    private RedisService redisService;
    @Autowired
    private ManufactorMapper manufactorMapper;
    @Value("${YS.HOSTADDRESS}")
    private String hostAddress;
    @Value("${YS.DEVONLY}")
    private String devonly;

    @Override
    public PageVo pageList(CommonDto commonDto) {
        Page page = new Page();
        // 设置当前页码
        page.setCurrent(commonDto.getPage());
        // 设置页大小
        page.setSize(commonDto.getLimit());
        IPage iPage = this.baseMapper.pageList(page, commonDto);
        List<Device> records = iPage.getRecords();
        for (Device d:records) {
            //获取redis中的设备
            Device device;
            if (d.getDevSysType().equals("728183")){
                String[] strArry = d.getRelationId().split("-");
                Manufactor manufactor = JSON.parseObject((String) redisService.get(strArry[0]), Manufactor.class);
                if (null== manufactor || manufactor.getIsOnline().equals("0")){
                    d.setStatus("离线");
                }else{
                    device = JSON.parseObject((String) redisService.get(d.getRelationId()+"_realtime"), Device.class);
                    if(device==null){
                        d.setStatus("正常");
                    }else{
                        d.setStatus(device.getStatus());
                    }
                }
            }else if (d.getDevSysType().equals("728184")){
                device = JSON.parseObject((String) redisService.get(d.getRelationId()+"_realtime_device"), Device.class);
                if(device==null){
                    d.setStatus("正常");
                }else{
                    d.setStatus(DataCleaningUtil.dataCleaning(device.getStatus()));
                }
            }else if (d.getDevSysType().equals("728195")) {
                device = JSON.parseObject((String) redisService.get(d.getRelationId()+"_realtime"), Device.class);
                if(device==null){
                    d.setStatus("离线");
                }else{
                    d.setStatus(device.getStatus());
                }
            }else if (d.getDevSysType().equals("728196") || d.getDevSysType().equals("728197")) {
                device = JSON.parseObject((String) redisService.get(d.getRelationId()+"_realtime"), Device.class);
                if(device==null){
                    d.setStatus("离线");
                }else{
                    d.setStatus(device.getStatus());
                }
            }else {
                device = JSON.parseObject((String) redisService.get(d.getRelationId()), Device.class);
                if(device==null){
                    d.setStatus("正常");
                }else{
                    d.setStatus(DataCleaningUtil.dataCleaning(device.getStatus()));
                }
            }
        }
        return new PageVo(iPage);

    }
    @Override
    public String getDeviceStatus(String deviceId){
        Device d=deviceMapper.selectById(deviceId);
        String bjzt = (String)redisService.get(d.getRelationId());
        if(StringUtils.isNotBlank(bjzt)){//判断缓存中是否存在
            return bjzt;
        }else{
            //缓存中不存在
            if("728181".equals(d.getDevSysType())){//火灾自动报警设备
                String fireDevStatus = deviceMapper.getFireDevStatus(d.getRelationId());
                return fireDevStatus;
            }else if("728183".equals(d.getDevSysType())){
                return deviceMapper.getWaterDevStatus(d.getRelationId());
            }else if("728184".equals(d.getDevSysType())){
                String electricalDevStatus = deviceMapper.getElectricalDevStatus(d.getRelationId());
                return electricalDevStatus;
            }
        }
        return null;
    }

    @Override
    public String getIconByDeviceId(String deviceId) {
        return deviceMapper.getIconByDeviceId(deviceId);
    }

    @Override
    public String getEscapeRouteIcon(String deviceId) {
        return deviceMapper.getEscapeRouteIcon(deviceId);
    }

    @Override
    public void editTopRui(TopRuiBean topRuiBean) {
        String FH =topRuiBean.getThresholdH();
        String FL =topRuiBean.getThresholdL();
        Date date = new Date();
        DateTime dateTime = DateUtil.offsetDay(date, 1);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String time = sdf.format(dateTime);
        String url="http://api.heclouds.com/nbiot/offline?imei="+topRuiBean.getRelationId()+"&obj_id=3200&obj_inst_id=0&mode=1&expired_time="+time+"T16:31:00";
        //String url = "http://api.heclouds.com/nbiot/offline?imei=862657051221384&obj_id=3200&obj_inst_id=0&mode=1&expired_time=2022-2-17T16:31:00";
        TopRuiEdit topRuiEdit = new TopRuiEdit();
        TopRuiEdit.DataBean dataBean = new TopRuiEdit.DataBean();
        List<TopRuiEdit.DataBean> list = new ArrayList< TopRuiEdit.DataBean >();
        dataBean.setRes_id(3200);
        String value = "{\"FH\":\""+FH+"\",\"FL\":\""+FL+"\",\"TH\":\"50.0\",\"TL\":\"0.0\",\"AT\":\"1\",\"CT\":\"3\",\"FF\":\"1.600\",\"TF\":\"5.0\",\"FB\":\"0.1\",\"TB\":\"2.0\",BR\":\"0\"}";
        dataBean.setVal(value);
        list.add(dataBean);
        topRuiEdit.setData(list);
        String json = JacksonUtil.toJson(topRuiEdit);
        HttpClientUtil.httpTopRui(url, json);
    }

    /**
     * 改维保端调用社会端  复制到base，
     */
    @Override
    public Object getDevicedetails(String relationId) {
        /*QueryWrapper<Device> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("relation_id",relationId);
        Device device = deviceMapper.selectOne(queryWrapper);*/
        Device device = deviceMapper.getDeviceByRelationId(relationId);
         if("728183".equals(device.getDevSysType())){
             Device device1 = JSON.parseObject((String) redisService.get(relationId), Device.class);
             if(device1!=null){
                 device.setStatus(device1.getStatus());
                 device.setCalculationValue(device1.getCalculationValue());
             }
             return device;
        }else if("728184".equals(device.getDevSysType())){
             return deviceMapper.getDeviceElectricalDetails(relationId);
        }

        return device;
    }

    @Override
    public int importDevice(Map<String,Object>params) {
        LoginUserVo user =(LoginUserVo) params.get("user");
        List<Device> deviceList = (List<Device>)params.get("deviceList");
        List<DeviceType> deviceTypes = (List<DeviceType>)params.get("deviceType");
        String maufactorIdentification=(String) params.get("maufactorIdentification");
        Manufactor manufactor = manufactorMapper.queryByIdentification(maufactorIdentification);
        List<Device> list = new ArrayList<>();
        //整理文件数据拼接关联字段relationId
        for (Device d:deviceList) {
            String relationId="";
            if(StringUtils.isNotBlank(d.getSecondaryCode()) && CommonConstant.HW.equals(manufactor.getTemplate())){
                relationId=maufactorIdentification+"-"+d.getSecondaryCode();
            }else if(StringUtils.isNotBlank(d.getHostNumber())&& StringUtils.isNotBlank(d.getLoopNumber())&& StringUtils.isNotBlank(d.getPartNumber())
                    && CommonConstant.QN.equals(manufactor.getTemplate())){
                relationId=maufactorIdentification+"-"+d.getHostNumber()+"-"+d.getLoopNumber()+"-"+d.getPartNumber();
            }else if(StringUtils.isNotBlank(d.getLoopNumber())&& StringUtils.isNotBlank(d.getPartNumber())
                    && CommonConstant.LD.equals(manufactor.getTemplate())){
                relationId=maufactorIdentification+"-"+d.getLoopNumber()+"-"+d.getPartNumber();
            }else{
                continue;
                //throw new RuntimeException("导入失败，请检查上传的文件信息");
            }
            if(StringUtils.isBlank(d.getName())){
                d.setName("未定义");
            }
            DeviceType type=null;
            //DeviceType type = deviceTypes.stream().filter(deviceType -> deviceType.getName().equals(d.getType())).collect(Collectors.toList()).get(0);
            List<DeviceType> typeList=deviceTypes.stream().filter(deviceType -> deviceType.getName().equals(d.getType())).collect(Collectors.toList());
            if(typeList.size()>0){
                type=typeList.get(0);
            }else{
                type=deviceTypes.stream().filter(deviceType -> deviceType.getName().equals("未定义")).collect(Collectors.toList()).get(0);
            }
            /*if(type ==null){
                type=deviceTypes.stream().filter(deviceType -> deviceType.getName().equals("未定义")).collect(Collectors.toList()).get(0);
            }*/
            d.setId(UUIDUtils.get32UUID());
            d.setUnitId(user.getEnterpriseId()+"");
            d.setMaufactorIdentification(maufactorIdentification);
            d.setType(type.getId());
            d.setRelationId(relationId);
            d.setCreateBy(user.getId()+"");
            d.setDevSysType("728181");
            list.add(d);
        }
        //删除该主机下原有设备
        deviceMapper.deleteDeviceByMaufactorIdentification(maufactorIdentification);
        //拆分文件list
        List<List<Device>> devList = splitListBycapacity(list, 5000);
        int count = 0;
        for (int i = 0; i < devList.size(); i++) {
            count += deviceMapper.importDevice(devList.get(i));
        }
        return count;
    }

    @Override
    public Device getDeviceByRelationId(String relationId) {
        return deviceMapper.getDeviceByRelationId(relationId);
    }

    @Override
    public Device bigDataDevice(String id) {
        return deviceMapper.bigDataDevice(id);
    }

    @Override
    public Device getByDevHisId(String devHisId) {
        return deviceMapper.getByDevHisId(devHisId);
    }

    @Override
    public List<DeviceTree> getDeviceTree(List<SysDirectory> devSysType,String unitId) {
        List<DeviceTree> treeList =new ArrayList<>();
        //获取智能设备
        DeviceTree deviceTree=new DeviceTree();
        deviceTree.setId("01");
        deviceTree.setName("智能设备");
        List<DeviceTree> deviceTreeList = deviceMapper.getDeviceTree(unitId);
        List<DeviceTree> devTreeList =new ArrayList<>();
        for (SysDirectory sysDirectory:devSysType) {
            String s = sysDirectory.getId().toString();
            int a=1;
            DeviceTree deviceTree1=new DeviceTree();
            deviceTree1.setId("010"+a);
            deviceTree1.setName(sysDirectory.getValue());
            //List<DeviceTree> collect = deviceTreeList.stream().filter(item -> item.getDevSysType().equals("728181")).collect(Collectors.toList());
            deviceTree1.setChildren(deviceTreeList.stream().filter(item -> item.getDevSysType().equals(s)).collect(Collectors.toList()));
            devTreeList.add(deviceTree1);
            a++;
        }
        deviceTree.setChildren(devTreeList);
        treeList.add(deviceTree);
        //获取传统设备
        DeviceTree traditioDeviceTree=new DeviceTree();
        traditioDeviceTree.setId("02");
        traditioDeviceTree.setName("传统设备");
        traditioDeviceTree.setChildren(deviceMapper.getTraditionDeviceTree(unitId));
        treeList.add(traditioDeviceTree);
        //获取救援设施
        DeviceTree rescueDeviceTree=new DeviceTree();
        rescueDeviceTree.setId("03");
        rescueDeviceTree.setName("救援设备");
        rescueDeviceTree.setChildren(deviceMapper.getRescueDeviceTree(unitId));
        treeList.add(rescueDeviceTree);
        //获取监控设备
        DeviceTree videoDeviceTree=new DeviceTree();
        videoDeviceTree.setId("04");
        videoDeviceTree.setName("监控设备");
        videoDeviceTree.setChildren(deviceMapper.getVideoDeviceTree(unitId));
        treeList.add(videoDeviceTree);
        //获取逃生通道
        DeviceTree escapeRouteTree=new DeviceTree();
        escapeRouteTree.setId("05");
        escapeRouteTree.setName("逃生通道");
        escapeRouteTree.setChildren(deviceMapper.getEscapeRouteTree(unitId));
        treeList.add(escapeRouteTree);
        //获取消防站
        DeviceTree stationDeviceTree=new DeviceTree();
        stationDeviceTree.setId("06");
        stationDeviceTree.setName("消防站");
        stationDeviceTree.setChildren(deviceMapper.getStationDeviceTree(unitId));
        treeList.add(stationDeviceTree);
        //获取重点部位
        DeviceTree partDeviceTree=new DeviceTree();
        partDeviceTree.setId("07");
        partDeviceTree.setName("重点部位");
        partDeviceTree.setChildren(deviceMapper.getPartDeviceTree(unitId));
        treeList.add(partDeviceTree);
        //获取危险源
        DeviceTree sourcesDeviceTree=new DeviceTree();
        sourcesDeviceTree.setId("08");
        sourcesDeviceTree.setName("危险源");
        sourcesDeviceTree.setChildren(deviceMapper.getSourcesDeviceTree(unitId));
        treeList.add(sourcesDeviceTree);
        return treeList;
    }
    @Override
    public List<DeviceTree> getDeviceTreeVideo(List<SysDirectory> devSysType,String unitId) {
        List<DeviceTree> treeList =new ArrayList<>();
        //获取监控设备
        DeviceTree videoDeviceTree=new DeviceTree();
        videoDeviceTree.setId("04");
        videoDeviceTree.setName("监控设备");
        videoDeviceTree.setChildren(deviceMapper.getVideoDeviceTree(unitId));
        treeList.add(videoDeviceTree);
        return treeList;
    }
    @Override
    public VideoPlayVo getVideoByDeviceId(String deviceId) {
        Video video = deviceMapper.getVideoByDeviceId(deviceId);
        String accessToken = getAccessToken(video.getVideoSerial(), video.getAppkey(), video.getAppsecret());

        VideoPlayVo videoPlayVo = new VideoPlayVo();
        videoPlayVo.setVideoSerial(video.getVideoSerial());
        videoPlayVo.setChannel(video.getChannel());
        videoPlayVo.setAccessToken(accessToken);

        videoPlayVo.setUserName(video.getUserName());
        videoPlayVo.setPassword(video.getPassword());
        videoPlayVo.setIp(video.getIp());
        videoPlayVo.setPort(video.getPort());
        videoPlayVo.setVedioType(video.getVedioType());
        videoPlayVo.setId(video.getId());

        return videoPlayVo;
    }

    /**
     * 获取AccessToken 并设置redis值
     *
     * @param gridCode
     * @return
     */
    public String getAccessToken(String gridCode, String appKey, String appSecret) {
        //从redis中获取token
        String accessToken = (String) redisService.get("AccessToken_" + gridCode);
        if (StringUtils.isBlank(accessToken)) {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("appKey", appKey);
            params.put("appSecret", appSecret);
            HttpClientResult result = null;
            try {
                result = HttpUtil.postWithForm(hostAddress, null, params);
                if (!result.isSuccess()) {
                    log.error("{}调用发生异常,result:{}", hostAddress, result);
                } else {
                    if (StringUtils.isNotBlank(result.getData())) {
                        String res = result.getData().substring(result.getData().indexOf("{"));
                        JSONObject resultObj = JSONUtil.parseObj(res);
                        String code = (String) resultObj.get("code");
                        String msg = (String) resultObj.get("msg");
                        if ("200".equals(code)) {
                            JSONObject dataObj = JSONUtil.parseObj(resultObj.get("data"));
                            accessToken = (String) dataObj.get("accessToken");
                            Long expireTime = (Long) dataObj.get("expireTime");
                            Long now = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
                            // 有效期 = 过期时间 - 现在 - 一天
                            //Long expire = (expireTime - now - (60 * 60 * 24 * 1000)) / 1000;
                            Long expire = 259200L;
                            // 普通缓存放入并设置时间
                            redisService.set("AccessToken_" + gridCode, accessToken, expire);
                        } else {
                            log.info("返回码：" + code);
                            log.info("返回信息：" + msg);
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return accessToken;
    }

    @Override
    public CrtVo getCrt(String deviceId) {
        CrtVo crt = deviceMapper.getCrt(deviceId);
        List<CrtPointVo> crtPoint = deviceMapper.getCrtPoint(crt.getId());
        crt.setCrtPointVos(crtPoint);
        return crt;
    }

    /**
     * 2> 根据目标容量 划分List
     *
     * @param source
     * @param capacity 划分完成的单个List容量
     * @param <T>
     * @return
     */
    private static <T> List<List<T>> splitListBycapacity(List<T> source, int capacity) {
        List<List<T>> result = new ArrayList<List<T>>();
        if (source != null){
            int size = source.size();
            if (size > 0 ){
                for (int i = 0; i < size;) {
                    List<T> value = null;
                    int end = i+capacity;
                    if (end > size){
                        end = size;
                    }
                    value = source.subList(i,end);
                    i = end;

                    result.add(value);
                }

            }else {
                result = null;
            }
        }else {
            result = null;
        }


        return result;
    }

    @Override
    public List<Device> getList(String unitId,String getList){
        return baseMapper.getList(unitId,getList);
    }


}
